<!--
 * @Author       : wfl
 * @LastEditors: fj
 * @description  :
 * @updateInfo   :
 * @Date         : 2022-11-08 15:48:46
 * @LastEditTime: 2023-09-08 15:51:38
-->
<i18n lang="yaml">
zh-cn:
  cache: 是否缓存
  nocache: 不缓存
  add: 新增菜单
  addBtn: 新增按钮
  edit: 修改菜单
  editBtn: 修改按钮
  addChild: 新增子菜单
  addChildBtn: 新增子按钮
  componentInfo: 请填写MainApp/views或MicroApp/views下的目录地址
  pathInfo: 仅一级菜单路径需要以'/'开始，子菜单请勿以'/'开始

  placeholder:
    name: 请输入菜单名称
    btnName: 请输入按钮名称
    tabName: 请输入Tab名称
    euName: 请输入英文名称
    link: 请输入链接地址
    route: 请输入路由地址
    jumpType: 请选择菜单跳转类型
    menuViewType: 请选择菜单可视类型
    icon: 请选择菜单图标
    btnIcon: 请选择按钮图标
    remark: 请输入菜单描述
    activeMenu: 请输入需选中菜单地址
    remarkBtn: 请输入按钮描述
    remarkTab: 请输入Tab描述
    menuType: 类型
    badge: 请输入徽标内容
    component: 请输入组件路径
    iframe: 请输入链接地址
    linkErr: 链接地址格式错误,例 http://xxxxxx.com
    permissionCode: 请输入权限码
  form:
    parent: 父级菜单
    framework: 路由类型
    name: 菜单名称
    btnName: 按钮名称
    tabName: Tab名称
    euName: 英文名称
    component: 组件路径
    keepAlive: 开启缓存
    noCache: 清除缓存
    visible: 是否显示
    jumpType: 跳转类型
    menuType: 类型
    menuViewType: 可视类型
    remark: 菜单描述
    remarkBtn: 按钮描述
    remarkTab: Tab描述
    icon: 图标
    activeIcon: 激活图标
    activeMenu: 高亮地址
    sidebar: 侧边栏显示
    breadcrumb: 面包屑显示
    defaultOpened: 次导航默认展开
    permanent: 常驻标签页
    badge: 徽标内容
    badgeType: 徽标类型
    copyright: 显示底部版权
    logo: 应用LOGO
    link: 外部链接
    route: 路由地址
    iframe: 内嵌链接
    permissionCode: 权限码
en:
  cache: Cache menu
  nocache: No cache
  add: Add Menu
  addBtn: Add button
  edit: Edit Menu
  editBtn: Edit button
  addChild: Add child menu
  addChildBtn: Add child button
  componentInfo: Please fill in the directory address under MainApp/views or MicroApp/views
  pathInfo: Only the first-level menu path needs to start with '/', do not start with '/' for submenus
  placeholder:
    name: Please enter a menu name
    btnName: Please enter a button name
    tabName: Please enter a tab name
    euName: Please enter the English name
    link: Please enter a link address
    route: Please enter a route address
    jumpType: Please select a menu jump type
    menuViewType: Please select menu visual type
    icon: Please select a menu icon
    btnIcon: Please select a button icon
    remark: Please enter a menu description
    activeMenu: Please enter a activeMenu path
    menuType: type
    badge: Please enter badge content
    component: Please enter component path
    remarkBtn: Please enter a button description
    remarkTab: Please enter a tab description
    iframe: Please enter a link address
    linkErr: The link address is in the wrong format, for example http://xxxxxx.com
    permissionCode: Please enter the permission code
  form:
    parent: Parent menu
    framework: Route type
    name: Menu name
    btnName: Button name
    tabName: Tab name
    euName: English name
    component: File address
    keepAlive: cache
    noCache: No cache
    visible: visible
    jumpType: Jump type
    menuType: type
    menuViewType: View Type
    remark: remark
    icon: icon
    activeIcon: Active icon
    activeMenu: Active menu
    sidebar: show in sidebar
    breadcrumb: show in breadcrumb
    defaultOpened: Default opened
    permanent: show in permanent
    badge: badge
    badgeType: Badge type
    copyright: Show copyright
    logo: logo
    link: External link
    route: Menu path
    iframe: Inline link
    permissionCode: Permission code
</i18n>

<script lang="ts" setup name="MenuForm">
import type { PropType } from 'vue'
import { _, ikValidate } from 'iking-utils'
import { useMenuDiction } from './diction'
import folderData from '@/assets/json/folder.json'
import { MenuBtnEnum, MenuJumpEnum } from '@/global/enums/menu'
const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  editData: {
    type: Object as PropType<any>,
    default: () => null
  },
  isChild: {
    type: Boolean,
    default: false
  },
  showAutoRender: {
    type: Boolean,
    default: false
  },
  labelWidth: {
    type: String,
    default: '140px'
  }
})
const { lenContent, lenName, lenLink, lenShort } = useLength()
const { t } = useConfig()
const { jumpTypes, menuTypes, menuViewTypes, frameworkTypes, badgeTypes }
  = useMenuDiction()

const formKey = {
  parent: '',
  parentId: '',
  name: '',
  // 菜单英文名称
  euName: '',
  // 是否为框架路由
  framework: false,
  // 组件路径
  component: '',
  // 缓存 - cache
  keepAlive: false,
  // 缓存规则
  cache: '',
  // 是否对该页面清除缓存，须设置 cache 才会生效
  noCache: '',
  // 显示
  visible: true,
  // 访问路径
  link: '',
  // 内嵌网页链接
  iframe: '',
  // 跳转类型
  jumpType: 'FRONT_ROUTE' as
    | 'EXTERNAL_LINK'
    | 'FRONT_ROUTE'
    | 'IFRAME'
    | 'NONE',
  // 类型
  menuType: 'MENU' as 'GLOBAL_BUTTON' | 'MENU' | 'PAGE_BUTTON',
  // 菜单可视类型
  menuViewType: 'MANAGE' as 'BUSINESS' | 'MANAGE' | 'MOBILE',
  // 菜单描述
  remark: '',
  paddingBottom: 0,
  // 菜单图标
  icon: '',
  // 导航激活时显示的图标
  activeIcon: '',
  // 指定高亮侧边栏路由，需要设置完整路由地址
  activeMenu: '',
  // 该路由是否在侧边栏导航中展示
  sidebar: true,
  // 该路由是否在面包屑导航中展示
  breadcrumb: true,
  // 次导航是否默认展开
  defaultOpened: false,
  // 是否常驻标签页
  permanent: true,
  // 导航标记 boolean / number / string
  badge: '',
  badgeType: '',
  // 该路由是否显示底部版权信息
  copyright: false,
  // 应用图标
  logo: '',
  autoRender: props.showAutoRender,
  btnIcon: '',
  btnName: '',
  permissionCode: ''
}

const menuFormRef = ref()
const menuForm = ref<any>(formKey)
const disableCom = ref(false)
const isRoute = computed(
  () => menuForm.value.jumpType === MenuJumpEnum.FRONT_ROUTE
)
const isLink = computed(
  () => menuForm.value.jumpType === MenuJumpEnum.EXTERNAL_LINK
)
const isMenu = ref(menuForm.value.menuType === MenuBtnEnum.MENU)
const isTab = computed(() => menuForm.value.menuType === MenuBtnEnum.PAGE_TAB)

const validateLink = (rule: any, value: any, cb: any) => {
  if (!value)
    cb(isRoute.value ? t('placeholder.route') : t('placeholder.iframe'))
  else if (!isRoute.value && !ikValidate.url.test(value))
    cb(t('placeholder.linkErr'))
  else cb()
}
const menuRules = {
  name: [{ required: true, trigger: 'blur', message: t('placeholder.name') }],
  btnName: [
    { required: true, trigger: 'blur', message: t('placeholder.btnName') }
  ],
  icon: [{ required: true, trigger: 'change', message: t('placeholder.icon') }],
  btnIcon: [
    { required: false, trigger: 'change', message: t('placeholder.btnIcon') }
  ],
  menuViewType: [
    {
      required: true,
      trigger: 'change',
      message: t('placeholder.menuViewType')
    }
  ],
  menuType: [
    { required: true, trigger: 'change', message: t('placeholder.menuType') }
  ],
  jumpType: [
    { required: true, trigger: 'change', message: t('placeholder.jumpType') }
  ],
  link: [{ required: true, trigger: 'blur', validator: validateLink }],
  iframe: [{ required: true, trigger: 'blur', validator: validateLink }],
  framework: [
    { required: true, trigger: 'blur', message: t('placeholder.framework') }
  ],
  autoRender: [{ required: true }],
  permissionCode: [
    {
      required: true,
      trigger: 'blur',
      message: t('placeholder.permissionCode')
    }
  ]
}

const menuDisabled = ref(false)
const frameworkDisabled = ref(false)
watch(
  () => menuForm.value.menuType,
  val => {
    if (val === MenuBtnEnum.MENU) {
      isMenu.value = true
    }
    else {
      isMenu.value = false
      // 新增时，清值
      if (!props.editData) {
        menuForm.value.component = ''
        menuForm.value.link = ''
      }
    }
  }
)

watch(
  () => props.visible,
  val => {
    if (!val) {
      menuForm.value = { ...formKey }
      menuFormRef.value?.resetFields()
    }
  }
)

const badgeChange = (val: string) => {
  switch (val) {
    case '':
    case 'point':
      menuForm.value.badge = val
      break
    case 'number':
      menuForm.value.badge = 0 as unknown as string
      break
    case 'string':
      menuForm.value.badge = ''
  }
}
const autoRenderChange = (val: any) => {
  if (val) {
    menuForm.value.component = 'function-design/auto-rander/index.vue'
    menuForm.value.menuType = MenuBtnEnum.MENU
    menuForm.value.framework = true
    menuDisabled.value = true
    frameworkDisabled.value = true
  }
  else {
    frameworkDisabled.value = false
  }
}
autoRenderChange(props.showAutoRender)
defineExpose({
  menuFormRef,
  menuForm
})

const init = () => {
  if (props.editData) {
    // disableCom.value = !(
    //   import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY === 'true'
    // )
    if (props.isChild) {
      menuForm.value.parent = props.editData.name
      menuForm.value.parentId = props.editData.id
    }
    else {
      menuForm.value = _.cloneDeep(props.editData)
      const flag = ['', 'point'].includes(props.editData?.badge)
      const type = ikValidate.number.test(props.editData?.badge)
        ? 'number'
        : 'string'
      menuForm.value = {
        ...menuForm.value,
        badgeType: flag ? props.editData?.badge : type,
        parent: props.isChild
          ? props.editData?.name
          : props.editData.parent,
        parentId: props.isChild
          ? props.editData?.id
          : props.editData.parentId,
        btnName: isMenu.value ? '' : menuForm.value.name,
        btnIcon: isMenu.value ? '' : menuForm.value.icon
      }
    }
    isMenu.value = menuForm.value.menuType === MenuBtnEnum.MENU
    menuForm.value = {
      ...menuForm.value,
      btnName: isMenu.value ? '' : menuForm.value.name,
      btnIcon: isMenu.value ? '' : menuForm.value.icon
    }
  }
}
init()
</script>

<template>
  <el-form
    ref="menuFormRef"
    :model="menuForm"
    :rules="menuRules"
    :label-width="labelWidth"
  >
    <el-row>
      <el-col v-if="isChild" :span="24">
        <el-form-item :label="t('form.parent')" prop="parent">
          <el-input
            v-model.trim="menuForm.parent"
            :maxlength="lenName"
            show-word-limit
            disabled
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item :label="t('form.menuType')" prop="menuType">
          <el-select
            v-model="menuForm.menuType"
            :disabled="menuDisabled"
            :placeholder="t('placeholder.menuType')"
          >
            <el-option
              v-for="item in menuTypes"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item v-if="isMenu" :label="t('form.framework')" prop="framework">
          <el-radio-group
            v-model="menuForm.framework"
            :disabled="frameworkDisabled"
          >
            <el-radio-button
              v-for="(item, index) in frameworkTypes"
              :key="index"
              :label="item.value"
              :value="item.value"
            >
              {{ item.label }}
            </el-radio-button>
          </el-radio-group>
        </el-form-item>
      </el-col>
      <el-col v-if="isMenu" :span="12">
        <el-form-item :label="t('form.name')" prop="name">
          <el-input
            v-model.trim="menuForm.name"
            clearable
            :maxlength="lenShort"
            show-word-limit
            :placeholder="t('placeholder.name')"
          />
        </el-form-item>
      </el-col>
      <el-col v-if="!isMenu" :span="12">
        <el-form-item :label="isTab ? t('form.tabName') : t('form.btnName')" prop="btnName">
          <el-input
            v-model.trim="menuForm.btnName"
            clearable
            :maxlength="lenShort"
            show-word-limit
            :placeholder="isTab ? t('placeholder.tabName') : t('placeholder.btnName')"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item :label="t('form.euName')" prop="euName">
          <el-input
            v-model.trim="menuForm.euName"
            :maxlength="lenName"
            show-word-limit
            clearable
            :placeholder="t('placeholder.euName')"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item :label="t('form.menuViewType')" prop="menuViewType">
          <el-select
            v-model="menuForm.menuViewType"
            :placeholder="t('placeholder.menuViewType')"
          >
            <el-option
              v-for="item in menuViewTypes"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      </el-col>
      <el-col v-if="!isMenu" :span="12">
        <el-form-item :label="t('form.permissionCode')" prop="permissionCode">
          <el-input
            v-model.trim="menuForm.permissionCode"
            :maxlength="lenName"
            show-word-limit
            clearable
            :placeholder="t('placeholder.permissionCode')"
          />
        </el-form-item>
      </el-col>
      <template v-if="isMenu">
        <el-col :span="12">
          <el-form-item :label="t('form.jumpType')" prop="jumpType">
            <el-select
              v-model="menuForm.jumpType"
              :placeholder="t('placeholder.jumpType')"
            >
              <el-option
                v-for="item in jumpTypes"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col v-if="menuForm.jumpType === MenuJumpEnum.IFRAME" :span="24">
          <el-form-item :label="t('form.iframe')" prop="iframe">
            <el-input
              v-model.trim="menuForm.iframe"
              :maxlength="lenLink"
              show-word-limit
              clearable
              :placeholder="t('placeholder.iframe')"
            />
          </el-form-item>
        </el-col>
        <template v-else>
          <el-col :span="24">
            <el-form-item
              :label="isLink ? t('form.link') : t('form.route')"
              prop="link"
            >
              <el-input
                v-model.trim="menuForm.link"
                :maxlength="lenLink"
                show-word-limit
                clearable
                :placeholder="
                  isLink ? t('placeholder.link') : t('placeholder.route')
                "
              />
              <span v-show="isRoute" class="title-info lineheight-1">{{
                t("pathInfo")
              }}</span>
            </el-form-item>
          </el-col>
          <el-col v-if="!isLink" :span="24">
            <el-form-item
              :label="t('form.activeMenu')"
              prop="activeMenu"
            >
              <el-input
                v-model.trim="menuForm.activeMenu"
                clearable
                :placeholder=" t('placeholder.activeMenu')
                "
              />
            </el-form-item>
          </el-col>
        </template>
        <el-col v-if="props.showAutoRender" :span="12">
          <el-form-item label="是否自动渲染页面" prop="autoRender">
            <el-switch
              v-model="menuForm.autoRender"
              inline-prompt
              active-text="是"
              inactive-text="否"
              @change="autoRenderChange"
            />
          </el-form-item>
        </el-col>
        <el-col v-if="isRoute" :span="24">
          <el-form-item :label="t('form.component')" prop="component">
            <el-tree-select
              v-model="menuForm.component"
              clearable
              filterable
              :disabled="disableCom || menuForm.autoRender"
              :placeholder="t('placeholder.component')"
              allow-create
              :data="[menuForm.framework ? folderData.main : folderData.micro]"
              node-key="value"
              :render-after-expand="false"
              :default-expanded-keys="['views']"
            />
            <!-- <el-input
                v-model="menuForm.component"
                :disabled="menuDisabled"
                clearable
                :placeholder="t('placeholder.component')"
              /> -->
            <span class="title-info lineheight-1">{{
              t("componentInfo")
            }}</span>
          </el-form-item>
        </el-col>
      </template>
      <el-col :span="24">
        <el-form-item
          :label="isMenu ? t('form.remark') : isTab ? t('form.remarkTab') : t('form.remarkBtn')"
          prop="remark"
        >
          <el-input
            v-model.trim="menuForm.remark"
            clearable
            :maxlength="lenContent"
            show-word-limit
            type="textarea"
            :placeholder="
              isMenu ? t('placeholder.remark') : isTab ? t('placeholder.remarkTab') : t('placeholder.remarkBtn')
            "
          />
        </el-form-item>
      </el-col>
      <template v-if="isMenu">
        <el-col :span="12">
          <el-form-item :label="t('form.badgeType')" prop="breadcrumb">
            <el-select
              v-model="menuForm.badgeType"
              :placeholder="t('placeholder.badgeType')"
              @change="badgeChange"
            >
              <el-option
                v-for="item in badgeTypes"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item
            v-if="menuForm.badgeType === 'number'"
            :label="t('form.badge')"
            prop="breadcrumb"
          >
            <el-input-number v-model="menuForm.badge" />
          </el-form-item>
          <el-form-item
            v-if="menuForm.badgeType !== 'number'"
            :label="t('form.badge')"
            prop="breadcrumb"
          >
            <el-input
              v-model.trim="menuForm.badge"
              :maxlength="lenName"
              show-word-limit
              :disabled="menuForm.badgeType !== 'string'"
              :placeholder="t('placeholder.badge')"
            />
          </el-form-item>
        </el-col>
      </template>
      <el-col v-if="isMenu" :span="8">
        <el-form-item :label="t('form.icon')" prop="icon">
          <IkIconPicker v-model="menuForm.icon" />
        </el-form-item>
      </el-col>
      <el-col v-if="!isMenu" :span="8">
        <el-form-item :label="t('form.icon')" prop="btnIcon">
          <IkIconPicker v-model="menuForm.btnIcon" />
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item :label="t('form.activeIcon')" prop="activeIcon">
          <IkIconPicker v-model="menuForm.activeIcon" />
        </el-form-item>
      </el-col>
      <template v-if="isMenu">
        <el-col :span="8">
          <el-form-item :label="t('form.logo')" prop="logo">
            <IkImageUpload
              v-model="menuForm.logo"
              notip
              :width="100"
              :height="100"
            />
          </el-form-item>
        </el-col>
      </template>
      <template v-if="isMenu">
        <el-col :span="8">
          <el-form-item :label="t('form.keepAlive')" prop="keepAlive">
            <el-switch
              v-model="menuForm.keepAlive"
              inline-prompt
              :active-text="t('msg.yes')"
              :inactive-text="t('msg.no')"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item :label="t('form.visible')" prop="visible">
            <el-switch
              v-model="menuForm.visible"
              inline-prompt
              :active-text="t('msg.yes')"
              :inactive-text="t('msg.no')"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item :label="t('form.sidebar')" prop="sidebar">
            <el-switch
              v-model="menuForm.sidebar"
              :disabled="!menuForm.visible"
              inline-prompt
              :active-text="t('msg.yes')"
              :inactive-text="t('msg.no')"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item :label="t('form.breadcrumb')" prop="breadcrumb">
            <el-switch
              v-model="menuForm.breadcrumb"
              :disabled="!menuForm.visible"
              inline-prompt
              :active-text="t('msg.yes')"
              :inactive-text="t('msg.no')"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item :label="t('form.copyright')" prop="copyright">
            <el-switch
              v-model="menuForm.copyright"
              inline-prompt
              :active-text="t('msg.yes')"
              :inactive-text="t('msg.no')"
            />
          </el-form-item>
        </el-col>
      </template>
    </el-row>
  </el-form>
</template>
